/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.tad.cdi.mods.properties;

import com.tad.cdi.mods.properties.annotations.ConfiguredBy;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import com.tad.cdi.mods.properties.cache.PropertyCache;
import java.util.Properties;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;
import org.slf4j.Logger;

/**
 *
 * @author johnament
 */
public class PropertyProducer {
    @Inject Logger logger;
    @Inject PropertyCache propertyCache;

    /**
     * Produces a java.util.Properties object based on the qualifier ConfiguredBy
     * and the injection point.
     *
     * Behavior is as follows:
     * - the value can be a System property or a path.
     * - If it's a system property, we convert it to the value of that property first
     *
     * - Then we check to see if the value now is an absolute path or a classpath entry
     * - We try both.
     */
    @Produces @ConfiguredBy("")
    public Properties produceProperties(InjectionPoint ip) {
        String value = ip.getAnnotated().getAnnotation(ConfiguredBy.class).value();
        Properties props;
        if(propertyCache.containsKey(value)) {
            logger.info("cached properties for :"+value);
            props = propertyCache.get(value);
        } else {
            logger.info("creating properties for :"+value);
            props = createProperties(ip);
            propertyCache.add(value,props);
        }
        return props;
    }

    private Properties createProperties(InjectionPoint ip) {
        Properties p = new Properties();
        String value = ip.getAnnotated().getAnnotation(ConfiguredBy.class).value();
        System.out.println("Producing properties with value.... "+value);
        if(value == null || value.equals("")) {
            //if the given file is empty, we can't load it too well.
            return p;
        }
        if(value.equals("SystemProperties"))
            return System.getProperties();
        String propValue = System.getProperty(value);
        if(propValue != null) {
            value = propValue;
        }

        File f = new File(value);
        if(f.exists() && !f.isDirectory()) {
            //so it's on the file system, let's load it.
            try{
                FileInputStream fis = new FileInputStream(f);
                p.load(fis);
                fis.close();
            } catch (IOException e) {
                System.out.println("Problem reading the file, ignoring.");
            }
        }
        //now we try to get it from the classpath, as a resource.
        try{
            InputStream is = this.getClass().getClassLoader().getResourceAsStream(value);
            p.load(is);
            is.close();
        } catch (Exception e) {
            System.out.println("Problem reading the file, ignoring.");
        }
        return p;
    }
}
